using System;
using System.IO;
using System.Web;
using com.paypal.wps.util;
using System.Collections.Specialized;

namespace ASPDotNetSamples
{
	/// <summary>
	///  Handles IPN Notifications. Based on value set in "INDIVIDUAL_LOGS" variable, there are two choices for logging. 
	///  If the value of variable "INDIVIDUAL_LOGS" is true then for each IPN transaction a new log file will be generated,
	///  else all transactions would  be logged in a common log file.
	/// 
	/// The log file should record all three IPN transactions.
	/// 1.Incoming IPN from the paypal server,
	/// 2.Postback IPN that sent out from the lisentner to the PayPal server . 
	/// 3.IPN validation from the paypal server based on the Posting back IPN.
	/// </summary>
	public class NotifyUrl : IHttpHandler
	{
		public bool IsReusable { get { return true; } }
		private const string AMPERSAND = "&";
		private const string EQUALS = "=";
		private static readonly char[] AMPERSAND_CHAR_ARRAY = AMPERSAND.ToCharArray();
		private static readonly char[] EQUALS_CHAR_ARRAY = EQUALS.ToCharArray();
		public string getDateTime()
		{
		return " DateTime: "+DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
		}
		public void ProcessRequest(HttpContext ctx)
		{
			/*
			 * set to true to write to individual log files.
			 * 
			 * */
			const bool INDIVIDUAL_LOGS = false;
			string logfilepath =				
				Path.Combine(
				Path.Combine(
				ctx.Server.MapPath(ctx.Request.ApplicationPath), 
				"logs"),
				INDIVIDUAL_LOGS ?
				DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".ipn.log" :
				Constants.PAYPAL_IPN_LOG
				);
			using (StreamWriter logfile = new StreamWriter(logfilepath, true))
			{
				try
				{	
					using (StreamReader reader = new StreamReader(ctx.Request.InputStream))
					{
						
						string incomingIpn = reader.ReadToEnd();
						logfile.WriteLine("*********************************************************************************************************************************************");
						/*
						*  Listen to the incoming IPN from  paypal server and record it to the log file with timestamp.
						* 
						* */
						logfile.WriteLine(" ");
						logfile.WriteLine("Incoming IPN:" +getDateTime());
						logfile.WriteLine("=============");
						foreach (string nvp in incomingIpn.Split(AMPERSAND_CHAR_ARRAY))
						{
							string[] tokens = nvp.Split(EQUALS_CHAR_ARRAY);
							if (tokens.Length >= 2)
							{
								string name = HttpUtility.UrlDecode(tokens[0]); 
								string valuepair = HttpUtility.UrlDecode(tokens[1]);
								logfile.WriteLine(name + " : " + valuepair);
							}
						}
						/*
						* IPN post back to the paypal server for validation and record it to the log file with timestamp.
						* 
						* */
						string ipnPostback = incomingIpn + "&cmd=_notify-validate";
						string ipnResponse = Utils.HttpPost(Constants.WEBSCR_URL, ipnPostback);
						logfile.WriteLine(" " );

						logfile.WriteLine("IPN Postback:"+getDateTime());
						logfile.WriteLine("=============");
						foreach (string Ipnnvp in ipnPostback.Split(AMPERSAND_CHAR_ARRAY))
						{
							string[] Ipntokens = Ipnnvp.Split(EQUALS_CHAR_ARRAY);
							if (Ipntokens.Length >= 2)
							{
								string Ipnname =  HttpUtility.UrlDecode(Ipntokens[0]); 
								string Ipnvaluepair = HttpUtility.UrlDecode(Ipntokens[1]); 
								logfile.WriteLine(Ipnname + " : " + Ipnvaluepair);
							}
						}
						/*
						* Record the Ipn Response to the log file with timestamp.
						* 
						* */
						logfile.WriteLine(" " );
						logfile.WriteLine("IPN Response: " + ipnResponse + getDateTime());
						logfile.WriteLine(" " );
						}
				}
				catch (Exception ex)
				{
					logfile.WriteLine(ex.ToString());
				}
			}
		}
	}
}
